<!--
 * @Date: 2023-04-14 10:07:04
 * @LastEditTime: 2023-05-10 11:23:23
-->
<template>
  <div class="data">
    <div class="action">
      <div>
        <a-input-search v-model="form.key" placeholder="搜索字符串" @search="search" />
        <a-button class="check_btn" type="primary" @click="reset">重置</a-button>
      </div>
      <div>
        <!-- 用来判断是否显示新增入口 -->
        <a-space>
          <a-button type="primary" v-if="addStrVisible" @click="newString">新增字符串</a-button>
          <a-button type="primary" v-if="transVisible" @click="newLanguage" ghost>新增语言</a-button>

          <a-button-group>
            <a-button type="primary" @click="auxiliaryTrans" ghost>辅助翻译</a-button>

            <a-popover v-model="auxiliaryTransVisible" trigger="click" placement="bottom">
              <a-button type="primary" ghost icon="down" />
              <a-radio-group v-model="auxiliaryTransValue" slot="content" @change="radioChange">
                <a-radio :value="0" :style="radioStyle">百度翻译</a-radio>
                <a-radio :value="1" :style="radioStyle">腾讯翻译</a-radio>
              </a-radio-group>
            </a-popover>
          </a-button-group>

          <a-button type="primary" v-if="exportVisible" @click="exportList" ghost>导出列表</a-button>
        </a-space>
      </div>
    </div>

    <div class="table" ref="tableRef">
      <a-table
        :columns="columns"
        :data-source="data"
        :pagination="pagination"
        :loading="loading"
        :scroll="{ x: scrollWidth, y: scrollHeight }"
        rowKey="id"
        bordered
      >
        <!-- 自定义表头 -->
        <template v-for="item in columns" :slot="item.dataIndex + 'Title'">
          <div class="title_box" :key="item.dataIndex">
            <span :class="routerName === 'translate' ? 'title' : ''">{{ item.label }} </span>

            <template>
              <a-tag class="default_tag" v-if="item.isDefault">默认</a-tag>
              <div class="iconfont_box" v-else-if="routerName === 'translate'">
                <a-tooltip>
                  <template slot="title">将默认语言自动翻译成{{ item.label }}</template>
                  <icon-font
                    class="iconfont translate_icon"
                    type="Iffanyi2"
                    @click="autoTrans(item)"
                    v-if="data.length"
                  />
                </a-tooltip>

                <a-icon type="caret-down" v-if="data.length" @click="clickIcon(item)" />
                <a-popover v-model="item.visible" placement="bottomRight">
                  <a-radio-group v-model="transChooseValue" slot="content" @change="transRadioChange">
                    <a-radio :value="1" :style="radioStyle">全自动翻译</a-radio>
                    <a-radio :value="2" :style="radioStyle">仅翻译未翻译部分</a-radio>
                  </a-radio-group>
                </a-popover>

                <icon-font class="iconfont delete_icon" type="Ifshanchu1" @click="deleteLanguage(item)" />
              </div>
            </template>
          </div>
        </template>

        <!-- 表格内容 -->
        <template v-for="item in columns" :slot="item.dataIndex" slot-scope="text, record">
          <template v-if="record.editable && item.dataIndex !== 'name'">
            <a-input :key="item.id" v-model="editingData[item.dataIndex]" />
            <a-icon type="redo" :key="item.id" @click="trans(item)" v-if="!item.isDefault" />
          </template>
          <template v-else>
            <a-tooltip placement="topLeft" :key="item.id">
              <template slot="title">{{ text }}</template>
              {{ text }}
            </a-tooltip>
          </template>
        </template>

        <template slot="action" slot-scope="text, record">
          <div class="editable-row-operations">
            <span v-if="record.editable">
              <a-space>
                <a-button type="link" @click="save(record)">保存</a-button>
                <a-button type="link" @click="cancel(record)">取消</a-button>
              </a-space>
            </span>
            <span v-else>
              <a-space :size="10">
                <a-button type="link" :disabled="editingName !== ''" @click="edit(record)">编辑</a-button>
                <a-button
                  type="link"
                  :class="['del_btn', { del_btn_disabled: editingName !== '' }]"
                  :disabled="editingName !== ''"
                  @click="del(record.id)"
                >删除</a-button
                >
                <a-button type="link" :disabled="editingName !== ''" @click="copy(record)">复制代码</a-button>
              </a-space>
            </span>
          </div>
        </template>
      </a-table>
    </div>

    <NewProject ref="projectRef" routerName="translate" @success="getData" @close="modalClose" />
    <NewString ref="stringRef" @success="listCUDSuccess" @close="modalClose" />
  </div>
</template>

<script>
import NewProject from '../project/createUpdate.vue'
import NewString from './createUpdate.vue'
import { Ellipsis } from '@/components'
import { deleteProjectLanguage } from '@/api/project'
import { deleteString, newStringLanguage, stringList, autoTrans } from '@/api/string'
import { download, parameterChange, projectDetails } from '@/utils/util'
import { baiduApi } from '@/api/language'
import { Icon } from 'ant-design-vue'

const IconFont = Icon.createFromIconfontCN({
  scriptUrl: '//at.alicdn.com/t/c/font_2767325_nm9cnun2k8.js'
})

// const rawColumns = []
export default {
  name: 'StringList',

  components: { NewProject, NewString, IconFont, Ellipsis },

  props: {
    treeSelectType: { type: Number, default: () => -1 },
    selectNode: { type: Object, default: () => {} },
    routerName: { type: String, default: () => 'string' }
  },

  data () {
    return {
      auxiliaryTransVisible: false,
      auxiliaryTransValue: 0,
      transChooseValue: 1,
      radioStyle: { display: 'block', height: '30px', lineHeight: '30px', marginRight: 0 },

      form: { key: '', project_id: '', app_id: '', module_id: '', string_id: '' },

      defaultLangObj: {},
      scrollWidth: 0,
      scrollHeight: 0,
      columns: [],
      columnsCache: [],
      dataRaw: [],
      data: [],
      dataCache: [],
      loading: false,
      pagination: {
        total: 0,
        current: 1,
        pageSize: 10,
        showSizeChanger: true,
        hideOnSinglePage: true,
        onChange: (page, pageSize) => this.handlePageChange(page, pageSize),
        onShowSizeChange: (current, size) => this.showSizeChange(current, size)
      },

      editingName: '',
      editingData: {}
    }
  },

  computed: {
    // 是否为翻译管理模块
    isTranslate () {
      return this.routerName === 'translate'
    },
    // 新增字符串按钮是否显示
    addStrVisible () {
      const TREE_LEVEL_ADD_STRING = 2
      const { treeSelectType, isTranslate } = this
      return !isTranslate && treeSelectType === TREE_LEVEL_ADD_STRING
    },
    // 是否显示导出列表按钮
    exportVisible () {
      const { isTranslate, form } = this
      const { project_id, app_id, module_id, string_id } = form
      return !isTranslate && (project_id || app_id || module_id || string_id)
    },
    // 翻译显示
    transVisible () {
      const { isTranslate, form } = this
      return isTranslate && form.project_id
    }
  },

  mounted () {
    this.getData()

    this.auxiliaryTransValue = Number(sessionStorage.getItem('auxiliaryTransValue')) ?? 0
    this.transChooseValue = sessionStorage.getItem('transChooseValue')
      ? Number(sessionStorage.getItem('transChooseValue'))
      : 1

    window.onresize = () => {
      if (Object.keys(this.selectNode).length) this.setColumnsData()
    }
  },

  methods: {
    /**
     * 获取数据并设置格式
     */

    // 获取列表数据
    getData () {
      this.columnsCache = []
      this.dataCache = []

      const { project_id, app_id, module_id, string_id } = this.form

      // 重置编辑内容
      if (this.editingName) {
        this.editingName = ''
        this.editingData = {}
      }
      // 有选中树节点
      if (project_id || app_id || module_id || string_id) {
        this.loading = true
        const { pagination, routerName } = this
        const { current: page, pageSize: limit } = pagination

        const params = { ...this.form, page, limit }
        if (routerName === 'translate') {
          params.page = 0
          delete params.limit
        }

        stringList(params)
          .then((res) => {
            if (res.code === 200) {
              const { head, list, count } = res.data
              this.pagination.total = count || list.length

              this.resetColumnsData(head)
              this.setTableData(list)
            }
          })
          .finally(() => {
            this.loading = false
          })
      }
    },
    // 获取表头数据并转化为合适格式
    resetColumnsData (head) {
      const columns = []

      let defaultTemp = {}
      head.forEach((item) => {
        const { language_name, language_code, language_id, is_default } = item
        const temp = { title: language_name, dataIndex: language_code, isDefault: is_default === 1, language_id }
        if (is_default === 0) columns.push(temp)
        else defaultTemp = temp
      })
      columns.unshift(defaultTemp)

      this.columnsCache = [...columns]
      this.setColumnsData()
    },
    // 设置表头
    setColumnsData () {
      this.columns = []

      const COLUMN_LENGTH = this.columnsCache.length
      const CLIENT_WIDTH = this.$refs.tableRef.clientWidth
      const NAME_WIDTH = 150
      const ACTION_WIDTH = 180
      let COLUMN_WIDTH = (CLIENT_WIDTH - NAME_WIDTH - ACTION_WIDTH) / COLUMN_LENGTH
      COLUMN_WIDTH = COLUMN_WIDTH < 180 ? 180 : COLUMN_WIDTH

      this.columnsCache = this.columnsCache.map((item) => ({ ...item }))
      this.columns.push({
        title: '字段名',
        dataIndex: 'name',
        align: 'center',
        scopedSlots: { customRender: 'name' },
        fixed: 'left',
        width: NAME_WIDTH,
        ellipsis: true
      })
      this.columnsCache.forEach((item) => {
        const temp = {
          dataIndex: item.dataIndex,
          align: 'center',
          ellipsis: true,
          scopedSlots: { customRender: item.dataIndex },
          width: COLUMN_WIDTH,
          slots: { title: item.dataIndex + 'Title' },
          label: item.title,
          visible: false,
          chooseValue: 1
        }

        if (item.isDefault) temp.isDefault = true

        this.columns.push(temp)
      })
      this.columns.push({
        title: '操作',
        key: 'action',
        dataIndex: 'action',
        align: 'center',
        scopedSlots: { customRender: 'action' },
        fixed: 'right',
        width: ACTION_WIDTH,
        ellipsis: true
      })

      let sum = 0
      this.columns.forEach((item) => {
        sum = sum + item.width
      })
      this.defaultLangObj = this.columnsCache.find((item) => item.isDefault)
      this.scrollWidth = sum > CLIENT_WIDTH ? sum : 0
    },
    // 获取列表数据并转化为合适格式
    setTableData (list) {
      const data = []
      list.forEach((item) => {
        const { string_id, string_name, string_language } = item
        const temp = { name: string_name, id: string_id }

        // 1、判断语言列表是否为空，如果为空，则遍历表头去初始化data的语言表，避免后面编辑时取消保存无法重置
        if (string_language.length) {
          string_language.forEach((i) => {
            const { language, string_text } = i
            temp[language.language_code] = string_text ?? ''
          })
        }
        // 判断语言列表长度与表头长度是否一致，如果不一致，将没内容的语言置空
        if (string_language.length !== this.columnsCache.length) {
          this.columnsCache.forEach((i) => {
            if (!temp[i.dataIndex]) temp[i.dataIndex] = ''
          })
        }
        data.push(temp)
      })
      this.dataRaw = [...list]
      this.data = data
      this.dataCache = data.map((item) => ({ ...item }))
    },

    /**
     * 表格上部操作
     */

    // 搜索
    search () {
      this.pagination.current = 1
      this.getData()
    },
    // 重置
    reset () {
      this.$set(this.form, 'key', '')
      this.$set(this.pagination, 'current', 1)
      this.getData()
    },
    // 新增字符串
    newString () {
      const { projectId, appId, moduleId } = this.selectNode
      this.$refs.stringRef.form.project_id = projectId
      this.$refs.stringRef.form.app_id = appId
      this.$refs.stringRef.form.module_id = moduleId
      this.$refs.stringRef.open()
    },
    // 新增字符串成功回调
    listCUDSuccess () {
      const { projectId } = this.selectNode
      this.$emit('listCUDSuccess', { selectId: projectId, editId: projectId })
    },
    // 单选框选中值变化
    radioChange (e) {
      this.auxiliaryTransVisible = false
      sessionStorage.setItem('auxiliaryTransValue', e.target.value)
    },
    // 辅助翻译
    auxiliaryTrans () {
      this.auxiliaryTransValue
        ? window.open('https://transmart.qq.com/zh-CN/index', '_blank')
        : window.open('https://fanyi.baidu.com/?aldtype=23#en/zh/', '_blank')
    },
    // 导出列表
    exportList () {
      const params = this.form
      delete params.page
      delete params.limit

      const baseUrl = process.env.VUE_APP_API_BASE_URL
      const apiUrl = '/web/string_mg/stringExport?' + parameterChange(this.form)
      const url = baseUrl + apiUrl
      const date = new Date()
      const name =
        (date.toLocaleDateString() + date.toLocaleTimeString()).replaceAll('/', '').replaceAll(':', '') + '_export.csv'
      download(url, name)
    },

    /**
     * 表格内操作
     */

    // 点击翻译图标
    clickIcon (item) {
      this.columns.map((i) => {
        i.visible = false
      })
      item.visible = true
    },
    // 翻译单选框选中值变化
    transRadioChange (e) {
      this.columns.map((i) => {
        i.visible = false
      })
      sessionStorage.setItem('transChooseValue', e.target.value)
    },
    // 自动翻译当前列
    autoTrans (column) {
      const { selectNode, transChooseValue: type } = this
      const { projectId: project_id } = selectNode
      const { dataIndex: after_language_code } = column
      const { language_id } = this.columnsCache.find((item) => item.dataIndex === after_language_code)

      this.$nextTick(() => {
        const params = { project_id, language_id, before_language_code: 'auto', after_language_code, type }
        this.loading = true
        autoTrans(params)
          .then((res) => {
            if (res.code === 200) {
              this.getData()
            } else this.$message.error(res.msg)
          })
          .finally(() => {
            this.loading = false
          })
      })
    },
    // 删除语言
    deleteLanguage (column) {
      this.$confirm({
        content: '确定删除该语言?',
        onOk: () => {
          const targetColumn = this.columnsCache.find((item) => item.dataIndex === column.dataIndex)
          const params = { project_id: this.selectNode.projectId, language: [targetColumn.language_id] }
          deleteProjectLanguage(params).then((res) => {
            if (res.code === 200) {
              this.$message.success(res.msg)
              this.getData()
            } else this.$message.error(res.msg)
          })
        },
        onCancel: () => {}
      })
    },
    // 手动单个翻译
    trans ({ dataIndex: toDataIndex }) {
      const { dataIndex } = this.defaultLangObj

      const params = { query: this.editingData[dataIndex], from: dataIndex, to: toDataIndex }
      baiduApi(params).then((res) => {
        if (res.code === 200) this.$set(this.editingData, [toDataIndex], res.data?.trans_result[0].dst)
        else this.$message.error(res.msg)
      })
    },
    // 删除字符
    del (id) {
      this.$confirm({
        content: '确认删除?',
        onOk: () => {
          deleteString({ string_id: id }).then((res) => {
            if (res.code === 200) this.listCUDSuccess()
          })
        }
      })
    },
    // 点击编辑按钮
    edit (record) {
      const { name, id } = record
      const newData = [...this.data]
      const target = newData.find((item) => id === item.id)
      this.editingName = name
      if (target) {
        target.editable = true
        this.data = newData
        this.editingData = target
      }
    },
    // 点击保存按钮
    save (e, isShowMsg = true) {
      delete e.editable
      const params = { string_id: e.id }
      const language_string = []
      this.columnsCache.forEach((item) => {
        const tempObj = {}
        tempObj.language_id = item.language_id
        tempObj.string_text = e[item.dataIndex]
        if (e[item.dataIndex]) language_string.push(tempObj)
      })
      params.language_string = language_string

      newStringLanguage(params).then((res) => {
        if (res.code === 200) {
          this.editingName = ''
          this.editingData = {}

          this.getData()
          if (isShowMsg) this.$message.success(res.msg)
        } else this.$message.error(res.msg)
      })
    },
    // 点击取消按钮
    cancel ({ id }) {
      const newData = [...this.data]
      const target = newData.find((item) => id === item.id)
      this.editingName = ''
      this.editingData = {}
      if (target) {
        Object.assign(
          target,
          this.dataCache.find((item) => id === item.id)
        )
        delete target.editable
        this.data = newData
      }
    },
    // 复制代码
    copy ({ id }) {
      const { project_name, app_name, module_name, string_name } = this.dataRaw.find((item) => item.string_id === id)
      const input = document.createElement('input')
      input.value = `${project_name}.${app_name}.${module_name}.${string_name}`
      document.body.appendChild(input)
      input.select()
      document.execCommand('copy')
      this.$message.success('复制成功！')
      document.body.removeChild(input)
    },
    // 新增语言
    newLanguage () {
      this.$refs.projectRef.open()
      this.$refs.projectRef.modalType = 1
      this.projectDetail(this.selectNode.projectId)
    },
    // 编辑项目
    projectDetail (project_id) {
      projectDetails(project_id).then((res) => {
        const { checkedArr, defaultLanguage, form } = res
        this.$refs.projectRef.checkedArr = checkedArr
        this.$refs.projectRef.defaultLanguage = defaultLanguage
        this.$refs.projectRef.form = form
      })
    },

    /**
     * 表格下部操作
     */

    // 翻页
    handlePageChange (page, pageSize) {
      this.pagination.current = page
      this.pagination.pageSize = pageSize
      this.getData()
    },
    // 更换每页显示
    showSizeChange (current, size) {
      this.pagination.current = current
      this.pagination.pageSize = size
      this.getData()
    },
    // 弹窗关闭
    modalClose () {
      this.editProjectId = -1
    }
  }
}
</script>

<style lang="less" scoped>
.data {
  width: 100%;
  height: 100%;

  .action {
    display: flex;
    align-items: center;
    justify-content: space-between;

    :deep(.ant-input-search) {
      width: 250px;
    }

    .check_btn {
      margin-left: 10px;
    }
  }

  .table {
    height: calc(100% - 32px);
    overflow-y: auto;
    margin-top: 20px;

    &::-webkit-scrollbar {
      width: 0;
    }

    :deep(.ant-table-thead > tr > th),
    :deep(.ant-table-tbody > tr > td) {
      padding: 8px 16px;

      .ant-input {
        width: calc(100% - 32px);
      }

      i.anticon.anticon-redo {
        margin-left: 5px;
        font-size: 18px;
      }
    }

    :deep(span.ant-table-header-column) {
      width: 100%;
      // height: 32px;
      // line-height: 32px;

      .title_box {
        position: relative;
        display: inline-flex;
        align-items: center;

        .title {
          width: 85px;
          white-space: pre-line;
        }

        .default_tag {
          margin-left: 10px;
          color: #8a8a8a;
          border-color: #8a8a8a;
        }

        .iconfont_box {
          height: 32px;
          display: flex;
          align-items: center;
          margin-left: 10px;
          // position: absolute;
          // right: 0;
          // top: 0;

          .iconfont {
            cursor: pointer;
            font-size: 16px;

            &.delete_icon {
              margin-left: 5px;
              color: red;
            }
          }

          i.anticon.anticon-caret-down {
            font-size: 10px;
            cursor: pointer;
            margin-left: 2px;
          }
        }
      }
    }

    .ant-btn {
      padding: 0;

      &.del_btn {
        color: red;

        &.del_btn_disabled {
          color: rgba(0, 0, 0, 0.25);
        }
      }
    }
  }
}

.circle {
  width: 10px;
  height: 10px;
  border: 1px solid;
  display: inline-block;
  border-radius: 50%;
  margin-left: 5px;
}
</style>
